﻿

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using lite;
using System.Data.SqlClient;
using Csla.Data;
using Csla;
using OpenExpressApp;
using System.Collections;
using Csla.Core;
using OpenExpressApp.ORM;
using OpenExpressApp.MetaAttribute;

namespace OrderLibrary
{
    [Serializable]
    public partial class OrderList : GReadOnlyListBase<OrderList, Order>
    {        
        #region  Factory Methods

        public static OrderList GetList()
        {
            return DataPortal.Fetch<OrderList>();
        }


        private OrderList()
        {     
            /* require use of factory methods */
            AllowNew = true;
            /* 不允许修改时，AutoUI绑定列表控件时会使得控件只读  */
            //AllowEdit = false;            
        }

        protected override object AddNewCore()
        {
            var item = Order.New();
            Add(item);
            return item;
        }

        #endregion

        #region  Data Access

        private void DataPortal_Fetch()
        {
            IsReadOnly = false;
            RaiseListChangedEvents = false;
            using (var ctx = ConnectionManager<SqlConnection>.GetManager("BusinessDBName"))
            {
                IDb db = DbFactory.Instance.GetDb(ctx.Connection);
                IQuery q = db.Query();
                var list = db.Select<Order>(q);
                foreach (var item in list)
                {
                    this.Add(Order.GetLazy(item.Id));
                }
            }
            RaiseListChangedEvents = true;
        }
        
        #endregion
    }

    [Serializable]
    [Table]
	[DefaultObject("43640D97-B892-4F56-A386-5228359ACC5C", Catalog="示例"), Label("订单")]
    public partial class Order : GBusinessBase<Order>
    {   
        #region  Business Methods

        private static PropertyInfo<Guid> IdProperty =
            RegisterProperty(new PropertyInfo<Guid>("Id"));
        [System.ComponentModel.DataObjectField(true, true)]
        [Column, PK][EntityProperty]
        [Indexable(IndexModeEnum.IndexModeAlways)]
        public Guid Id
        {
            get { return GetProperty(IdProperty); }
            set { SetProperty(IdProperty, value); }
        }

        private static PropertyInfo<string> NameProperty =
          RegisterProperty(new PropertyInfo<string>("Name"));
        [Column]
        [EntityProperty]
        [Required, IsTitle, ShowInListAttribute, ShowInDetail, Label("名称")]
        public string Name
        {
            get { return GetProperty(NameProperty); }
            set { SetProperty(NameProperty, value); }
        }


        private static PropertyInfo<OrderItems> OrderItemsProperty =
          RegisterProperty(new PropertyInfo<OrderItems>("OrderItems"));
        [Association]
        public OrderItems OrderItems
        {
            get
            {
                if (!FieldManager.FieldExists(OrderItemsProperty))
                {
                    LoadProperty(OrderItemsProperty, OrderItems.NewChild());
                }
                return GetProperty(OrderItemsProperty);
            }
        }

        public override BusinessBase MergeOldObject(BusinessBase oldObject)
        {
            if (null == oldObject) return null;

            Order _detailItem = oldObject as Order;

            LoadProperty(IdProperty, _detailItem.Id);
            LoadProperty(NameProperty, _detailItem.Name);
           // LoadProperty(DescriptionProperty, _detailItem.Description);
            var orderItems = OrderItems.NewChild();
            orderItems.AddRange((oldObject as Order).OrderItems);
            LoadProperty(OrderItemsProperty, orderItems);
            
            return base.MergeOldObject(oldObject);
        }

        #endregion

        #region  Validation Rules

        protected override void AddBusinessRules()
        {
           // ValidationRules.AddRule(Csla.Validation.CommonRules.StringRequired, new Csla.Validation.RuleArgs(NameProperty));
        }

        #endregion

        #region  Factory Methods
        
        private Order()
        { 
            IsObjectLazy = true; 
        }

        public static Order New()
        {
            return DataPortal.Create<Order>();
        }

        public static Order Get(Guid id)
        {
            return DataPortal.Fetch< Order>(new SingleLazyCriteria<Order, Guid>(id, false));
        }

        internal static Order GetLazy(Guid id)
        {
            return DataPortal.Fetch< Order>(new SingleLazyCriteria<Order, Guid>(id, true));
        }

        public static void Delete(Guid id)
        {
            DataPortal.Delete(new SingleCriteria<Order, Guid>(id));
        }

        #endregion

        #region  Data Access
       
        [RunLocal()]
        protected override void DataPortal_Create()
        {
            LoadProperty(IdProperty, Guid.NewGuid());
            ValidationRules.CheckRules();
        }

        private void DataPortal_Fetch(SingleLazyCriteria<Order, Guid> criteria)
        {
            using (var ctx = ConnectionManager<SqlConnection>.GetManager("BusinessDBName"))
            {
                IDb db = DbFactory.Instance.GetDb(ctx.Connection);
                IQuery q = db.Query();
                q.Constrain("Id").Equal(criteria.Value);
                var data = db.Select<Order>(q)[0];
                LoadProperty(IdProperty, data.Id);
                LoadProperty(NameProperty, data.Name);
               // LoadProperty(DescriptionProperty, data.Description);
                this.IsObjectLazy = criteria.IsObjectLazy;
                if (!IsObjectLazy)
                {
                    LoadProperty(OrderItemsProperty, OrderItems.GetChild(this));
                }
                
            }
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_Insert()
        {
            using (var ctx = ConnectionManager<SqlConnection>.GetManager("BusinessDBName"))
            {
                IDb db = DbFactory.Instance.GetDb(ctx.Connection);
                db.Insert(this);
                // update child objects
                FieldManager.UpdateChildren(this);
            }
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_Update()
        {
            using (var ctx = ConnectionManager<SqlConnection>.GetManager("BusinessDBName"))
            {
                IDb db = DbFactory.Instance.GetDb(ctx.Connection);
                db.Update(this);
                // update child objects
                FieldManager.UpdateChildren(this);
            }
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        protected override void DataPortal_DeleteSelf()
        {
            DataPortal_Delete(this.Id);
        }

        [Transactional(TransactionalTypes.TransactionScope)]
        private void DataPortal_Delete(Guid id)
        {
            using (var ctx = ConnectionManager<SqlConnection>.GetManager("BusinessDBName"))
            {
                IDb db = DbFactory.Instance.GetDb(ctx.Connection);
                db.Delete(typeof(Order), db.Query().Constrain("Id").Equal(id));
            }

        }

        #endregion
        
        public override string ToString()
        {
            return Name;
        }
    }
}